﻿#include <string>
#include <windows.h>
#include <utility>

#include "inifile.h"

using namespace std;

int MyIni::_bufLen=1024;

MyIni::MyIni(void)
{
}

MyIni::MyIni(char*_iniFilePath)
{
    strcpy_s(iniFilePath,_iniFilePath);
}

MyIni::~MyIni(void)
{
}

//获取所有的section名
void MyIni::getAllSections(vector<string>& vecSections)
{
    vecSections.clear();

    char *buf=new char[_bufLen];
    myGetPrivateProfileSectionNames(&buf,_bufLen);

    /*
    **通过string来取出每个section的依据
    **GetPrivateProfileSectionNames取出的sections以\0间隔，存于buf中
    **string遇见\0就终止
    */
    char*p=buf;
    string strName=p;
    while(strName.length()!=0)
    {
        vecSections.push_back(strName);
        p+=strName.length()+1;
        strName=p;
    }

    delete []buf;
}

//通过section名，该section下所有的key-value
void MyIni::getKeyValueBySection(const char* sectionName,map<string,string>& kv)
{
    char *buf=new char[_bufLen];
    myGetPrivateProfileString(sectionName,NULL,&buf,_bufLen);

    kv.clear();
    char *p=buf;
    string strKey=p;
    while(strKey.length()!=0)
    {
        kv.insert(make_pair(strKey,getValueString(sectionName,strKey.c_str())));
        p+=strKey.length()+1;
        strKey=p;
    }
    delete []buf;
}

//判断是否存在指定的section
bool MyIni::isSectionExists(const char* sectionName)
{
    vector<string> vec;
    getAllSections(vec);

    string strSec=sectionName;
    int count=vec.size();
    for(int i=0;i<count;i++)
    {
        if(vec[i]==strSec)
        {
            return true;
        }
    }

    return false;
}
//判断是否存在指定的key
bool MyIni::isKeyExists(const char*sectionName,const char*keyName)
{
    bool isExists=false;
    //不必判断section是否存在
    char *buf=new char[_bufLen];
    myGetPrivateProfileString(sectionName,NULL,&buf,_bufLen);

    char *p=buf;
    string strKey=p;
    string strKeyTemp=keyName;
    while(strKey.length()!=0)
    {
        if(strKey==strKeyTemp)
        {
            isExists=true;
            break;
        }
        p+=strKey.length()+1;
        strKey=p;
    }
    delete []buf;

    return isExists;
}

//private 供getValueString和getKeyValueBySection调用
void MyIni::myGetPrivateProfileString(const char*sectionName,const char*keyName,char **buf,int bufLen)
{
    DWORD dwRes=GetPrivateProfileString(sectionName,keyName,NULL,*buf,bufLen,iniFilePath);
    while(dwRes==bufLen-2)
    {
        delete [](*buf);
        bufLen+=1024;
        *buf=new char[bufLen];
        dwRes=GetPrivateProfileString(sectionName,keyName,NULL,*buf,bufLen,iniFilePath);
    }
}

//private 供getSectionCount和getAllSections调用
void MyIni::myGetPrivateProfileSectionNames(char** buf,int bufLen)
{
    DWORD dwRes=GetPrivateProfileSectionNames(*buf,bufLen,iniFilePath);
    //缓冲区过小,重新设置缓冲区
    while(dwRes==bufLen-2)
    {
        delete []buf;
        bufLen+=1024;
        *buf=new char[bufLen];
        dwRes=GetPrivateProfileSectionNames(*buf,bufLen,iniFilePath);
    }
}
//获取section的个数
int MyIni::getSectionCount()
{
    char *buf=new char[_bufLen];
    myGetPrivateProfileSectionNames(&buf,_bufLen);

    int count=0;
    char *p=buf;
    string str=p;
    while(str.length()!=0)
    {
        count++;
        p+=str.length()+1;
        str=p;
    }
    delete []buf;
    return count;
}
//获取该section下key-value的个数
int MyIni::getKeyValueCount(const char* sectionName)
{
    char *buf=new char[_bufLen];
    myGetPrivateProfileString(sectionName,NULL,&buf,_bufLen);

    int count=0;
    char *p=buf;
    string strKey=p;
    while(strKey.length()!=0)
    {
        count++;
        p+=strKey.length()+1;
        strKey=p;
    }
    delete []buf;
    return count;
}

//写入字符值
void MyIni::writeKeyValue(const char*sectionName,const char*keyName,const char*value)
{
    ::WritePrivateProfileString(sectionName,keyName,value,iniFilePath);
}

//删除section
void MyIni::deleteSection(const char* sectionName)
{
    ::WritePrivateProfileString(sectionName,NULL,NULL,iniFilePath);
}
//删除section中的某个键
void MyIni::deleteKey(const char* sectionName,const char* keyName)
{
    ::WritePrivateProfileString(sectionName,keyName,NULL,iniFilePath);
}

//获取section下某个key的值，必须确保key存在
string MyIni::getValueString(const char*sectionName,const char*keyName)
{
    char *buf=new char[_bufLen];
    myGetPrivateProfileString(sectionName,keyName,&buf,_bufLen);
    string str=buf;
    delete []buf;
    return str;
}

//获取section下某个key的值，如果该section或key不存在，返回false
bool MyIni::getValueInt(const char*sectionName,const char*keyName,int& result)
{
    if(this->isKeyExists(sectionName,keyName))
    {
        result=GetPrivateProfileInt(sectionName,keyName,-1,iniFilePath);
        return true;
    }
    else
        return false;
}
